package Lambda表达式;

import org.w3c.dom.ls.LSOutput;

import javax.crypto.spec.PSource;
import java.util.Comparator;
import java.util.PriorityQueue;

@FunctionalInterface
//加 @FunctionalInterface注解后，编译器就会自动检测，按照函数式接口的定义要求该接口
interface B{
    //函数式接口：接口中只能有 一个抽象方法
    void funOnly();
    default void fun(){
        //这不是抽象方法，jdk1.8里，允许接口中有非抽象方法
    }
}

//1.无返回值 无参数
@FunctionalInterface
interface NoParameterNoReturn {
    void test();
}
//2.无返回值 一个参数
@FunctionalInterface
interface OneParameterNoReturn {
    void test(int a);
}
//3.无返回值 多个参数
@FunctionalInterface
interface MoreParameterNoReturn {
    void test(int a,int b);
}
//4.有返回值 无参数
@FunctionalInterface
interface NoParameterReturn {
    int test();
}

//5.有返回值 一个参数
@FunctionalInterface
interface OneParameterReturn {
    int test(int a);
}
//6.有返回值 多参数
@FunctionalInterface
interface MoreParameterReturn {
    int test(int a,int b);
}


@FunctionalInterface
interface MoreParameterReturn2 {
    double test(int a,double b);
}

interface A{
    //普通接口
    void func1();
    void func2();
}
public class TestDemo {
    public static void main1(String[] args) {
        //没有返回值的测试
        NoParameterNoReturn noParameterNoReturn = ()->{
            //左边是 函数式接口
            //右边是 写接口中的方法
            System.out.println("hhhh");
        };
        noParameterNoReturn.test();

        OneParameterNoReturn oneParameterNoReturn= (a) -> System.out.println(a);//当花括号中只有 1条语句可以省略花括号

        oneParameterNoReturn.test(10);

        MoreParameterNoReturn moreParameterNoReturn=(a,b)->{
            System.out.println(a+b);
        };
        moreParameterNoReturn.test(10,20);


        //有返回值的测试
        NoParameterReturn noParameterReturn=()->{
            return 1;
        };
        int ret = noParameterReturn.test();
        System.out.println(ret);

        //简写上述,当花括号中只有 1条语句可以省略花括号
        NoParameterReturn noParameterReturn1=()->1;
        ret=noParameterReturn1.test();
        System.out.println(ret);

//        OneParameterReturn oneParameterReturn=(a) -> a;
        OneParameterReturn oneParameterReturn=a -> a;
        ret=oneParameterReturn.test(55);
        System.out.println(ret);

//        MoreParameterReturn moreParameterReturn=(a,b)->{return a+b;};
//        MoreParameterReturn moreParameterReturn=(a,b)-> a+b;
        MoreParameterReturn moreParameterReturn=(int a,int b)-> a+b;
        ret=moreParameterReturn.test(10,7);
        System.out.println(ret);


        PriorityQueue<Integer> priorityQueue=new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1-o2;
            }
        });
        PriorityQueue<Integer> priorityQueue2=new PriorityQueue<>( (o1,o2)->{return o1-o2;} );
        //( (o1,o2)->{return o1-o2;} )  实现了Comparator接口，重写了compare()方法，实现小堆，代码量减少但是代码可读性变差

    }

    public static void main2(String[] args) {

        int a=10;
        //a=5;
        new Test() {
            //匿名内部类
            public void func() {
                //a=99;
                //匿名内部类中，捕获变量的前提是 变量不能修改过
                //捕获的变量，在编译期间 或 整个程序运行期间没有发生改变的量
                //捕获的变量：要么是一个常量，要么是一个没有改变过值的变量
                System.out.println("捕获的变量："+ a);
            }
        }.func();
    }

    public static void main(String[] args) {
        int a=10;
        //a=5;
        NoParameterReturn noParameterReturn=()->{
            //a=99;
            //lambda表达式捕获变量
            //捕获的也是在 整个编译期间 或 整个程序运行期间没有发生改变的量
            //捕获的变量：要么是一个常量，要么是一个没有改变过值的变量
            System.out.println("捕获的变量："+ a);
            return 1;
        };
        int ret = noParameterReturn.test();
        System.out.println(ret);
    }

}

class Test {
}
